package com.bclz.baseLearn

import scala.annotation.tailrec

class FunctionPra {

}

object FunctionPra {

  def main(args: Array[String]) {

    def everyAddOne(ai: List[Int]): List[Int] = {

      @tailrec
      def ops(ai1: List[Int], ai2: List[Int]): List[Int] = {

        if (ai2 == Nil) ai1
        else ops(ai1 ::: (ai2.head + 1) :: Nil, ai2.tail)

      }

      ops(Nil, ai)
    }

    def everyToString(ds: List[Double]): List[String] = {

      @tailrec
      def ops(ds1: List[String], ds2: List[Double]): List[String] = {
        if (ds2 == Nil) ds1
        else ops(ds1 ::: ds2.head.toString() :: Nil, ds2.tail)
       
      }
      ops(Nil, ds)
    }
    
    def map[A,B](as:List[A],f:A=>B):List[B]={
      
      
      @tailrec
      def ops(as2:List[B], as:List[A]): List[B] = {
        if (as == Nil) as2
        else ops(as2 ::: f(as.head) :: Nil, as.tail)
       
      }
      
      ops(Nil,as)
    }
    
    def filter[A](as:List[A])(f:A=>Boolean):List[A]={
      
      def ops (as1:List[A],as2:List[A]):List[A]={
        
        if(as2==Nil) as1
        else if(f(as2.head)) ops(as1:::as2.head::Nil,as2.tail)
        else ops(as1,as2.tail)
        
      }
      ops(Nil,as)
    }
    
    def flatMap[A,B](as:List[A])(f:A=>List[B]):List[B]={
      
      def ops(as1:List[B],as2:List[A]):List[B]={
        
        if(as2==Nil) as1
        else ops(as1:::f(as2.head),as2.tail)
      }
      ops(Nil,as)
    }
    
    def filter2[A](as:List[A])(f:A=>Boolean):List[A]={
      
      flatMap[A,A](as)(a=>if(f(a)) List(a) else Nil)
      
    }
    
    def sumListEle(as1:List[Int],as2:List[Int]):List[Int]={
      
      var sumList:List[Int]=Nil
      def ops(as1:List[Int],as2:List[Int]):List[Int]={
        
        if(as1==Nil||as2==Nil) sumList
        else{
          sumList=sumList:::(as1.head+as2.head)::Nil
          ops(as1.tail,as2.tail)
        }
      }
      
      ops(as1,as2)
    }
    
    def zipWith[A,B,C](as1:List[A],as2:List[B])(f:(A,B)=>C):List[C]={
      
      var zipList:List[C]=Nil
      
      @tailrec
      def ops(as1:List[A],as2:List[B]):List[C]={
        
        if(as1==Nil||as2==Nil) zipList
        else{
          zipList=zipList:::f(as1.head,as2.head)::Nil
          ops(as1.tail,as2.tail)
        }
      }
      
      ops(as1,as2)
      
    }
    
    def hasSubsequence[A](sup:List[A],sub:List[A]):Boolean={
        
      
        def judge[A](sup1:List[A],sub1:List[A]):Boolean={
          if(sub1==Nil) true
          else if(sup1.length<sub1.length) false
          else if(sup1.head==sub1.head) judge(sup1.tail,sub1.tail)
          else judge(sup1.tail,sub)
        }
      
        judge(sup,sub)
    }
    
    println(everyAddOne(List(1, 2, 3, 4)))
    println(everyToString(List(1d, 2d, 3d, 4d)))
    println(map[Int,Int](List(1, 2, 3, 4),a=>a+1))
    println(map[Double,String](List(1.0, 2.0,   3.0, 4.0),a=>a.toString()))
    println("过滤后的结果"+filter(List(1, 2, 3, 4))(l=>l%2!=0))
    println("flatMap实现过滤后的结果"+filter(List(1, 2, 3, 4))(l=>l%2!=0))
    println(flatMap[Int,Double](List(1, 2, 3, 4))(a=>List(a.toDouble,a.toDouble)))
    println(sumListEle(List(1, 2, 3, 4),List(44, 22, 33, 41)))
    println(hasSubsequence(List(1, 2, 3, 4),List(1, 2, 3, 4,5)))
  }

}